Spring笔记(3):IOC容器

您所在的位置:网站首页 spring 重新注入 Spring笔记(3):IOC容器

Spring笔记(3):IOC容器

#Spring笔记(3):IOC容器| 来源: 网络整理| 查看: 265

1、IOC容器是什么? IOC容器是Spring容器的重要组成部分,它具有依赖注入功能,负责实例化、定位、配置Bean对象,并建立对象之间依赖。 通过配置(Metadata),由Spring容器创建对象,这个配置是对应POJO对象类的属性进行注入,创建完毕后发送给ApplicationContext容器进行渲染。

在这里插入图片描述

2、两种Spring常见IOC容器

Spring BeanFactory容器:是一种最简单的容器,通过BeanFactory接口定义。

Spring Application容器:是一种企业级容器,通过ApplicationContext接口定义

因为ApplicationContext容器包括BeanFactory的功能,所以通常不使用BeanFactory。 BeanFactory优点也明显,数据吞吐量和速度是优秀的。

3、Spring BeanFactory容器 Spring有大量对BeanFactory接口的实现,其最常使用的是XmlBeanFactory类。 XmlBeanFactory——功能是读取XML文件的配置数据形成BeanFactory 我们从介绍上也能看出来,XmlBeanFactory的数据来源是XML配置,并且在声明它时需要加载XML文件。

User.java

public class User { private String uid; private String uname; public User() { } public User(String uid, String uname) { this.uid = uid; this.uname = uname; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } @Override public String toString() { return "User{" + "uid='" + uid + '\'' + ", uname='" + uname + '\'' + '}'; } }

Main.java

public class Main { public static void main(String[] args) { XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml")); User user = (User) factory.getBean("user"); System.out.println(user.toString()); } }

Beans.xml

bean-id: bean对象的唯一编号 bean-name:bean对象的名称 bean-class:bean注入对象 property-name:注入对象属性名 property-value:注入对象属性值

我们需要什么依赖呢? pom.xml

org.springframework spring-beans 5.3.18 org.springframework spring-core 5.3.20

一定要注意版本兼容问题,会报异常哦~

输出结果

User{uid='123123', uname='这是我的名字'}

4、Spring ApplicationContext容器

Application Context是BeanFacctory的子接口,也称为Spring上下文。可以加载配置文件中定义的bean,在请求状态下分配bean对象。另外增加了企业所需要的功能,例如从属性文件中解析文本和传递事件给监听器。通过context.ApplicationContext 接口定义。

加载XML文件的三种方式

FileSystemXmlApplicationContext: 通过扫描XML文件绝对路径进行载入ClassPathXmlApplicationContext: 通过扫描XML文件相对路径进行载入XmlWebApplicationContext: 在一个web应用程序范围内加载XML文件

需要ApplicationContext依赖——Spring Context pom.xml

org.springframework spring-context 5.3.18

要注意版本兼容问题

Main.java

public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("D:/JavaWebProgram/BeanDemo/src/main/resources/Beans.xml"); User user = (User) context.getBean("user"); System.out.println("绝对路径下的Bean:"+user.toString()); context = new ClassPathXmlApplicationContext("Beans.xml"); user = (User) context.getBean("user"); System.out.println("相对路径下的Bean:"+user.toString()); } }

输出结果

绝对路径下的Bean:User{uid='123123', uname='这是我的名字'} 相对路径下的Bean:User{uid='123123', uname='这是我的名字'}

5、Spring Bean

5.1 Spring Bean定义

Bean对象是构成应用程序的单元,被Spring IOC容器管理。 Bean定义包含配置元数据。

可以配置什么元数据?

Bean的创建Bean的生命周期Bean的依赖关系

Bean的属性

属性描述class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。

Bean与Spring容器的关系

步骤1: 扫描XML,扫描注解,配置类获取元数据步骤2: Spring容器定义注册表步骤3: Bean实现类实例化Bean对象,并装载入缓存池中步骤4: 应用程序调取缓存池中的Bean对象 在这里插入图片描述

Spring配置元数据

有哪些方法可以配置元数据给Spring容器

基于XML的配置文件()基于注解的配置(@Autowire)基于Java的配置(@Configuration)

5.2 Spring Bean 作用域

scope有哪些作用域值呢?

singleton: Bean以单例模式存在,即getBean时,是同一个Bean对象prototype: Bean以原型模式存在,即getBean时,是不同的Bean对象request: 每次HTTP请求创建新的Bean,仅适用于WebApplicationContext环境session: 同一个Session会话共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境global-session: 应用于Portlet应用环境,仅适用于WebApplicationContext环境

什么是Portlet? 它是一种基于Java的web组件化网页,看起来有点复古,支持Servlet进行HTTP的请求反馈。

singleton 作用域 singleton是默认作用域,如果你不指定scope,就只有一个Bean对象给你蹂躏。 singleton的创建时间是与容器一同被创建。

Main.java

public class Main { public static void main(String[] args) { ApplicationContext context; User user1,user2; context = new ClassPathXmlApplicationContext("Beans.xml"); user1 = (User) context.getBean("user"); System.out.println("user1:"+user1); user1.setUname("真差劲诶"); user2 = (User) context.getBean("user"); System.out.println("user2:"+ user2); } }

输出结果

user1:User{uid='123123', uname='这是我的名字'} user2:User{uid='123123', uname='真差劲诶'}

我们可以看到,在user1的set方法后,获取到的user2就是set后的数据,即这个bean是同一个对象。

prototype 作用域

prototype是一个原型模式下作用域,能够对应多实例,可以类比父类,getBean出来的则是一个它的子类,每一次get都是不同的子类。

我们在刚刚的程序文件上,只改动scope的值 输出结果

user1:User{uid='123123', uname='这是我的名字'} user2:User{uid='123123', uname='这是我的名字'}

我们可以清晰的知道,它们是两个不同的对象,所以才不会受到user1对象的set方法影响。

5.3 Spring Bean 生命周期

Bean的定义Bean的初始化Bean的使用Bean的销毁

两种重要生命周期

init-method:调取初始化方法 destroy-method:调取销毁方法

初始化回调与销毁回调

InitalizingBean接口实现初始化回调方法 DestroyBean接口实现销毁回调方法

User.java

package org.example.POJO; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 包名:BeanDemo * 作者:章恩光 * 时间:2023/3/5 22:09 周日 */ public class User implements InitializingBean, DisposableBean { private String uid; private String uname; public User() { } public User(String uid, String uname) { this.uid = uid; this.uname = uname; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public void init(){ System.out.println("Bean is going through init"); } public void destroy(){ System.out.println("Bean will destroy now"); } @Override public String toString() { return "User{" + "uid='" + uid + '\'' + ", uname='" + uname + '\'' + '}'; } @Override public void afterPropertiesSet() throws Exception { System.out.println("UserBean has created。"); } }

Beans.xml

Spring容器执行顺序:

步骤1: 注入对象实现InitializingBean, DisposableBean接口,需要编写的方法有init(),destroy(),afterPrepartiesSet()步骤2:

提供默认初始化和销毁方法

5.4 Spring Bean 后置处理器

什么是Bean 后置处理器? Bean的拓展坞,在初始化前后进行处理

怎么实现后置处理器? BeanPostProcessor接口定义回调方法

可以用该方法进行优化Spring容器启动效率,例如编写自己的实例化逻辑,依赖解析逻辑;可以在Spring容器中插入若干个BeanPostProcessor实现实例化,配置和初始化一个bean之后实现自定义逻辑回调方法;可以配置多个BeanPostProcessor接口,通过设置BeanPostProcessor.Ordered接口提供的order属性来控制BeanPostProcessor顺序。

注意:

Application自动检测后置处理器实现的bean,再通过容器创建bean。自定义接口实现类中,必须实现的方法: BeanPostProcessor.postProcessBeforeInitialization(Object, String)​ ​BeanPostProcessor.postProcessAfterInitialization(Object, String)

初始化类InitUser.java

public class InitUser implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("AfterInitialization:"+beanName); return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeforeInitialization:"+beanName); return bean; } }

Beans.xml

加载初始化后置处理器

输出结果

BeforeInitialization:user UserBean has created。 Bean is going through init AfterInitialization:user username:这是我的名字

执行过程顺序:

后置器BeforeInitialization执行Bean注册表创建Bean执行init()方法后置器AfterInitialization执行使用BeanBean执行destroy()方法

5.5 Spring Bean 定义继承

bean定义可以包含很多配置信息:包括构造函数参数,属性值,初始化方法,静态工厂方法名等等

继承bean可以重写值,或添加值。

它们之间的关系:与抽象类继承类的关系相同。

Bean 定义模板



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3